﻿namespace Basefr.Core.Extensions
{
    public static class PredicateExtensions
    {
        ///// <summary>
        ///// 主键查询
        ///// </summary>
        //public static Expression<Func<TEntity, bool>> HasId<TEntity, TPrimaryKey>(this Expression<Func<TEntity, bool>> predicate, TPrimaryKey id)
        //    where TEntity : EntityBase<TPrimaryKey>
        //    where TPrimaryKey : struct
        //{
        //    if (!id.Equals(default(TPrimaryKey)))
        //    {
        //        return predicate.And(p => p.Id.Equals(id));
        //    }

        //    return predicate;
        //}

        ///// <summary>
        ///// 值类型属性相等
        ///// </summary>
        //public static Expression<Func<TEntity, bool>> ValueEquals<TEntity, TValue>(this Expression<Func<TEntity, bool>> predicate, Func<TEntity, TValue> property, TValue value)
        //{
        //    return predicate.And(p => property.Invoke(p).Equals(value));
        //}

        ///// <summary>
        ///// 值类型属性相等（带条件）
        ///// </summary>
        //public static Expression<Func<TEntity, bool>> ValueEqualsWhen<TEntity, TValue>(this Expression<Func<TEntity, bool>> predicate, Func<TEntity, TValue> property, TValue value, Func<TValue, bool> condition)
        //{
        //    if (condition == null || condition.Invoke(value))
        //    {
        //        return predicate.And(p => property.Invoke(p).Equals(value));
        //    }

        //    return predicate;
        //}

        ///// <summary>
        ///// 一个字符串属性Contains
        ///// </summary>
        //public static Expression<Func<TEntity, bool>> StringContains<TEntity>(this Expression<Func<TEntity, bool>> predicate, Func<TEntity, string> property, string value)
        //{
        //    if (!string.IsNullOrWhiteSpace(value))
        //    {
        //        value = value.Trim();
        //        return predicate.And(p => property.Invoke(p).Contains(value));
        //    }

        //    return predicate;
        //}
        //TODO: Invoke方法在EFCore3.0中失效

        ///// <summary>
        ///// 多个字符串属性Contains（或）
        ///// 这个写法不太自然，为了实现不定参数数量，将value写在前面
        ///// 这个不太常用，所以单独定义，没有重载StringContains
        ///// </summary>
        //public static Expression<Func<TEntity, bool>> MultipleStringContains<TEntity>(this Expression<Func<TEntity, bool>> predicate, string value, Func<TEntity, string> property, params Func<TEntity, string>[] otherProperties)
        //{
        //    if (!string.IsNullOrWhiteSpace(value))
        //    {
        //        value = value.Trim();

        //        Expression<Func<TEntity, bool>> result = p => property.Invoke(p).Contains(value);

        //        otherProperties.ToList().ForEach(prop => result = result.Or(r => prop.Invoke(r).Contains(value)));

        //        return predicate.And(result);
        //    }

        //    return predicate;
        //}

        ///// <summary>
        ///// 一个字符串属性相等
        ///// </summary>
        //public static Expression<Func<TEntity, bool>> StringEquals<TEntity>(this Expression<Func<TEntity, bool>> predicate, Func<TEntity, string> property, string value)
        //{
        //    if (!string.IsNullOrWhiteSpace(value))
        //    {
        //        return predicate.And(p => property.Invoke(p) == value);
        //    }

        //    return predicate;
        //}

        ///// <summary>
        ///// 集合任意元素相等
        ///// </summary>
        //public static Expression<Func<TEntity, bool>> ListAnyEquals<TEntity, TListItem>(this Expression<Func<TEntity, bool>> predicate, Func<TEntity, TListItem> property, ICollection<TListItem> list)
        //{
        //    if (list?.Any() ?? false)
        //    {
        //        return predicate.And(p => list.Any(item => property.Invoke(p).Equals(item)));
        //    }

        //    return predicate;
        //}

        ///// <summary>
        ///// 时间日期属性大于等于
        ///// </summary>
        //public static Expression<Func<TEntity, bool>> DateAfter<TEntity>(this Expression<Func<TEntity, bool>> predicate, Func<TEntity, DateTime> property, DateTime? value)
        //{
        //    if (value.HasValue)
        //    {
        //        return predicate.And(p => property.Invoke(p) >= value);
        //    }

        //    return predicate;
        //}

        ///// <summary>
        ///// 时间日期属性小于等于
        ///// </summary>
        //public static Expression<Func<TEntity, bool>> DateBefore<TEntity>(this Expression<Func<TEntity, bool>> predicate, Func<TEntity, DateTime> property, DateTime? value)
        //{
        //    if (value.HasValue)
        //    {
        //        value = value.Value.AddDays(1);

        //        return predicate.And(p => property.Invoke(p) < value);
        //    }

        //    return predicate;
        //}

    }
}
